package com.example.common.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Date;

/**
 * Date <=> LocalDate
 * Date <=> LocalTime
 * Date <=> LocalDateTime
 * long <=> Date
 * Date          <=> 格式化
 * LocalDate     <=> 格式化
 * LocalDateTime <=> 格式化
 */
public class DateUtils {
    //todo 1代表/ _代表- $代表空格
    public enum DateFormat {
        format_yyyy1MM1dd$hhmmss("yyyy/MM/dd HH:mm:ss"),
        format_yyyy_MM_dd$hhmmss("yyyy-MM-dd HH:mm:ss"),
        format_yyyy年MM月dd日$hh时mm分ss秒("yyyy年MM月dd HH时mm分ss秒"),
        format_yyyy年MM月dd日$hh时mm分("yyyy年MM月dd HH时mm分");
        private String format;

        DateFormat(String format) {
            this.format = format;
        }

        public String getFormat() {
            return format;
        }
    }

    /**
     * Date => LocalDate
     *
     * @param date
     * @return
     */
    public static LocalDate date2LocalDate(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        LocalDate localDate = localDateTime.toLocalDate();
        return localDate;
    }

    /**
     * LocalDate => Date
     *
     * @param localDate
     * @return
     */
    public static Date localDate2Date(LocalDate localDate) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        Date date = Date.from(instant);
        return date;
    }

    /**
     * Date => LocalTime
     *
     * @param date
     * @return
     */
    public static LocalTime date2LocalTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        LocalTime localTime = localDateTime.toLocalTime();
        return localTime;
    }

    /**
     * LocalTime => Date
     *
     * @param localTime
     * @return
     */
    public static Date localTime2Date(LocalTime localTime) {
        return null;
    }

    /**
     * Date => LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime date2LocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        return localDateTime;
    }

    /**
     * LocalDateTime => Date
     *
     * @param localDateTime
     * @return
     */
    public static Date localDateTime2Date(LocalDateTime localDateTime) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDateTime.atZone(zone).toInstant();
        Date date = Date.from(instant);
        return date;
    }

    /**
     * Date => long
     *
     * @param date
     * @return
     */
    public static long date2Long(Date date) {
        long time = date.getTime();
        return time;
    }

    /**
     * Date => long
     *
     * @param time
     * @return
     */
    public static Date date2Long(long time) {
        Date date = new Date(time);
        return date;
    }

    /**
     * 时间转字符串
     *
     * @param date
     * @param dateFormat
     * @return
     */
    public static String date2Str(Date date, DateFormat dateFormat) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat.getFormat());
        String str = sdf.format(date);
        return str;
    }

    /**
     * 字符传转时间
     *
     * @param str
     * @param dateFormat
     * @return
     */
    public static Date str2Date(String str, DateFormat dateFormat) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat.getFormat());
        Date date = new Date();
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 操作年月日
     * @param date
     * @param year
     * @param month
     * @param day
     * @return
     */
    public static Date operationDate(Date date,int year,int month,int day) {
        LocalDateTime localDateTime = date2LocalDateTime(date);
        LocalDateTime newLocalDateTime = localDateTime.plusYears(year)
                .plusMonths(month)
                .plusDays(day);
        return localDateTime2Date(newLocalDateTime);
    }

    /**
     * 操作时分秒
     * @param date
     * @param hour
     * @param minute
     * @param second
     * @return
     */
    public static Date operationTime(Date date,int hour,int minute,int second) {
        LocalDateTime localDateTime = date2LocalDateTime(date);
        LocalDateTime newLocalDateTime = localDateTime.plusHours(hour)
                .plusMinutes(minute)
                .plusSeconds(second);
        return localDateTime2Date(newLocalDateTime);
    }

    /**
     * 操作年月日时分秒
     * @param date
     * @param year
     * @param month
     * @param day
     * @param hour
     * @param minute
     * @param second
     * @return
     */
    public static Date operationDateTime(Date date,int year,int month,int day,int hour,int minute,int second) {
        Date date1 = operationDate(date, year, month, day);
        Date date2 = operationTime(date1, hour, minute, second);
        return date2;
    }


    public static void main(String[] args) {
        Date date = operationDate(new Date(), 0, 0, -13);
        String s = date2Str(date, DateFormat.format_yyyy_MM_dd$hhmmss);
        System.out.println("s = " + s);
    }
}
